package cfca.seal.quarz;

import cfca.sadk.algorithm.common.PKIException;
import cfca.sadk.x509.certificate.X509CRL;
import cfca.seal.dao.main.ITempFilePdfDao;
import cfca.seal.exception.CodeException;
import cfca.seal.mananger.CrlManager;
import cfca.seal.system.Env;
import cfca.seal.util.FileUtil;
import cfca.seal.util.StringUtil;
import cfca.seal.util.TimeUtil;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Date;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Component
public class UpdateCrlFileTask
{
  private static final Logger log = LoggerFactory.getLogger("web_sys");

  @Resource
  ITempFilePdfDao tempFilePdfDao;

  public void work() throws Exception {
    try { log.info("CRL更新定时任务 开始 ");

      Date date = TimeUtil.getCurrentTime();
      log.info("当前时间 " + TimeUtil.getFormatDate(date));

      String[] settings = Env.CRLSourceFiles.split(";");
      for (int i = 0; i < settings.length; i++)
        if (!StringUtil.isEmpty(settings[i]))
        {
          String[] setItems = settings[i].split("@");
          if (setItems.length != 2) {
            log.warn("配置文件中CRL更新源文件设置格式错误: " + settings[i]);
          }
          else
          {
            updateCrlFile(setItems[0], setItems[1]);
          }
        }
      log.info("CRL更新定时任务 结束 ");
    } catch (CodeException ce) {
      log.info("更新CRL文件发生异常:" + ce.getMessage());
      throw ce;
    } catch (Exception e) {
      log.info("更新CRL文件发生异常:" + e.getMessage());
      throw new CodeException("C0001", e.getMessage());
    }
  }

  private void updateCrlFile(String fileDirectory, String fileNameNoSuffix) throws CodeException, IOException, PKIException {
    File updateSourceFile = new File(fileDirectory + File.separator + fileNameNoSuffix);
    log.info("读取的源文件=" + updateSourceFile);
    if ((!updateSourceFile.exists()) || (!updateSourceFile.isFile()) || (updateSourceFile.length() <= 0L)) {
      throw new CodeException("C7081", "CRL文件更新中读取的源文件不存在或为空");
    }
    byte[] crlFileBytes = FileUtil.getBytesFromInputStream(new FileInputStream(updateSourceFile));
    log.info("读取的源文件大小=" + crlFileBytes.length);

    X509CRL x509CRL = new X509CRL(crlFileBytes);
    Date nextUpdate = x509CRL.getNextUpdate();
    log.info("读取的源文件CRL的预定下次更新时间=" + TimeUtil.getFormatDate(nextUpdate));
    if ((!CrlManager.offline_crl) && (new Date().after(nextUpdate))) {
      throw new CodeException("C7082", "配置要求检查CRL,CRL文件更新中读取的源文件更新时间已经过期");
    }
    String issuerKey = StringUtil.formatIssuerKey(x509CRL.getIssuer());
    log.info("读取的源文件CRL的Issuer=" + issuerKey);

    String newCrlFileDirStr = Env.crlResourceDir + File.separator + issuerKey;
    File newCrlFileDir = new File(newCrlFileDirStr);
    if (!newCrlFileDir.exists()) {
      newCrlFileDir.mkdirs();
    }
    log.info("更新目的文件目录=" + newCrlFileDirStr);

    String newCrlFileAbsolutePath = newCrlFileDirStr + File.separator + "crl.crl";
    log.info("更新目的文件路径=" + newCrlFileAbsolutePath);
    String tempCrlFileAbsolutePath = newCrlFileAbsolutePath + new Date().getTime();

    FileUtil.saveDataToFile(crlFileBytes, tempCrlFileAbsolutePath);
    log.info("生成更新目的目录下临时文件=" + tempCrlFileAbsolutePath);

    File tempFile = new File(newCrlFileAbsolutePath);
    log.info("更新目的文件:exists=" + tempFile.exists() + ",canRead=" + tempFile.canRead() + ",canWrite=" + tempFile.canWrite() + ",canExecute=" + tempFile.canExecute());

    FileUtil.replaceFile(newCrlFileAbsolutePath, tempCrlFileAbsolutePath);
    log.info("生成更新目的文件=" + newCrlFileAbsolutePath);

    CrlManager.updateCrlPool(issuerKey, x509CRL);
  }
}